#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<cerrno>
#include<stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
using namespace std;
void Usage(const string& proc)
{
  cout << "Usage:\t" << "proc port"<<endl;
}
//./udp_server port
int main(int argc,char* argv[])
{
  if(argc != 2)
  {
    Usage(argv[0]);
    exit(1);
  }
  int sock = socket(AF_INET,SOCK_DGRAM,0);
  if(sock < 0)
  {
    perror("socket:");
    exit(2);
  }
  struct sockaddr_in local;
  memset(&local,0,sizeof(local));
  socklen_t len = sizeof(local);
  local.sin_family = AF_INET;
  local.sin_port = htons(atoi(argv[1]));//端口号 主机序-》网络字节序！！！
  local.sin_addr.s_addr = INADDR_ANY;

  if(bind(sock,(struct sockaddr*)&local,len) < 0)
  {
    perror("bind:");
    exit(3);
  }
  //业务处理
  bool quit = false;
#define NUM 1024
  char buffer[NUM] = {0};
  while(!quit)
  {
    memset(buffer,0,sizeof(buffer));
    struct sockaddr_in peer;//记录客户端的网络信息
    socklen_t len = sizeof(peer);
    ssize_t ret = recvfrom(sock,buffer,sizeof(buffer-1),0,(struct sockaddr*)&peer,&len);
    if(ret > 0)
    {
      buffer[ret] = '\0';
      cout << "client:#" <<" "<<buffer<<endl;

      FILE* fp = popen(buffer,"r");
      char res[NUM] = {0};//读取文件内容
      string str;
      if(nullptr != fp)
      {
        while(fgets(res,sizeof(res),fp) != nullptr)
        {
            str+= res;
        }
        //把结果进行响应
        sendto(sock,str.c_str(),str.size(),0,(struct sockaddr*)&peer,len);
      }
      pclose(fp);
    }
    else
    {
      cerr << "recvfrom err" << endl;
    }
  }
  return 0;
}